#include "cgwidget.h"
#include <Cg/cg.h>
#include <Cg/cgGL.h>

static CGcontext Context = NULL;
static CGprogram VertexProgram = NULL;

static CGparameter KdParam = NULL;
static CGparameter ModelViewProjParam = NULL;
static CGparameter VertexColorParam = NULL;

#ifdef __APPLE__

static CGprofile VertexProfile = CG_PROFILE_ARBVP1;
#else 
static CGprofile VertexProfile = CG_PROFILE_VP20;
#endif


GLfloat CubeNormals[6][3] ={
	{-1.0,0.0,0.0},
	{0.0,1.0,0.0},
	{1.0,0.0,0.0},
	{0.0,-1.0,0.0},
	{0.0,0.0,1.0},
	{0.0,0.0,-1.0}
};

GLint  CubeFaces[6][4] = {
	{0,1,2,3},
	{3,2,6,7},
	{7,6,5,4},
	{4,5,1,0},
	{5,6,2,1},
	{7,4,0,3}
};

GLfloat CubeVertices[8][3];

void CGWidget::drawCube()
{
	int i ;
	cgGLBindProgram(VertexProgram);
	if(KdParam!= NULL){
		cgGLSetParameter4f(KdParam,1.0,1.0,0.0,1.0);
		if(ModelViewProjParam!= NULL){
			cgGLSetStateMatrixParameter(ModelViewProjParam,CG_GL_MODELVIEW_PROJECTION_MATRIX,CG_GL_MATRIX_IDENTITY);
			cgGLEnableProfile(VertexProfile);
		}
	}
	for(i=0;i<6;++i){
		glBegin(GL_QUADS);
		glNormal3fv(&CubeNormals[i][0]);
		cgGLSetParameter3f(VertexColorParam,1.0,0.0,0.0);
		glVertex3fv(&CubeVertices[CubeFaces[i][0]][0]);
		cgGLSetParameter3f(VertexColorParam,0.0,1.0,0.0);
		glVertex3fv(&CubeVertices[CubeFaces[i][1]][0]);
		cgGLSetParameter3f(VertexColorParam,0.0,0.0,1.0);
		glVertex3fv(&CubeVertices[CubeFaces[i][2]][0]);
		cgGLSetParameter3f(VertexColorParam,1.0,1.0,1.0);
		glVertex3fv(&CubeVertices[CubeFaces[i][2]][0]);
		glEnd();
	}
	cgGLDisableProfile(VertexProfile);
}


CGWidget::CGWidget(QWidget *parent)
	: QGLWidget(parent)
{
	
}

CGWidget::~CGWidget()
{
	cgDestroyProgram(VertexProgram);
	cgDestroyContext(Context);
}

void CGWidget::initializeGL()
{
	glClearColor(1.0,0.5,0.2,1.0);
	glClearDepth(1.0);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	initializeCube(CubeVertices);

	//initialize CG 
	Context = cgCreateContext();
	VertexProgram = cgCreateProgramFromFile(Context,CG_SOURCE,"vertexShader.cg",VertexProfile,NULL,NULL);
	if(VertexProgram!= NULL){
		cgGLLoadProgram(VertexProgram);
		KdParam = cgGetNamedParameter(VertexProgram,"Kd");
		ModelViewProjParam = cgGetNamedParameter(VertexProgram,"ModelViewProj");
		VertexColorParam = cgGetNamedParameter(VertexProgram,"IN.VertexColor");
	}
	
	//CGparameter parameter = cgGetNamedParameter(VertexProgram,"vertexColor");
	//cgSetParameter4f(parameter,0.0,1.0,0.0,1.0);

	//cgGLSetTextureParameter();
	//cgUpdateProgramParameters(vertexProgram);
	
}

void CGWidget::initializeCube(GLfloat v[8][3])
{
	v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
}

void CGWidget::resizeGL(int w, int h )
{
	if(h==0)
		h=1;
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(90.0,(GLfloat)w/h,0.1,1000.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void CGWidget::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	gluLookAt(0.0,0.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

	cgGLBindProgram(VertexProgram);
	cgGLEnableProfile(VertexProfile);

	drawCube();

	cgGLDisableProfile(VertexProfile);
	glFlush();
}

void CGWidget::drawTriangle()
{
	glBegin(GL_TRIANGLES);
		glVertex3f(-1.0,0.0,0.0);
		glVertex3f(1.0,0.0,0.0);
		glVertex3f(0.0,1.0,0.0);
	glEnd();
}